package com.yg.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yg.config.FilePathConfig;
import com.yg.config.result.R;
import com.yg.config.result.ResultCode;
import com.yg.entity.readAndWriteTemplates.CourseBuildRead;
import com.yg.entity.singleTemplates.CourseBuild;
import com.yg.mapper.CourseBuildMapper;
import com.yg.service.CourseBuildService;
import com.yg.utils.DateValidationUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 对应sheet09，此表为课程建设表 服务实现类
 * </p>
 *
 * @author YingGu
 * @since 2020-11-04
 */
@Slf4j
@Service
public class CourseBuildServiceImpl extends ServiceImpl<CourseBuildMapper, CourseBuild> implements CourseBuildService {

    @Autowired
    CourseBuildMapper courseBuildMapper;
    @Autowired
    FilePathConfig filePathConfig;

    /**
     * excel写入
     *
     * @param fileInputStream
     * @return
     */
    @Transactional
    @Override
    public R readExcel(FileInputStream fileInputStream) {
        //创建要录入的bean的list
        List<CourseBuild> courseBuildList = new ArrayList<>();
        //创建R
        R r = R.getR();
        r.setCode(ResultCode.SUCCESS);
        //存储错误信息
        List<String> errorList = new ArrayList<>();

        //读取excel
        EasyExcel.read(fileInputStream, CourseBuildRead.class, new AnalysisEventListener<CourseBuildRead>() {
            //每行执行
            @Override
            public void invoke(CourseBuildRead courseBuildRead, AnalysisContext analysisContext) {
                //创建数据库对应实体类
                CourseBuild courseBuild = new CourseBuild();
                courseBuildRead.setStart(DateValidationUtil.dateValidation(courseBuildRead.getStart(), "yyyy.MM"));
                courseBuildRead.setEnd(DateValidationUtil.dateValidation(courseBuildRead.getEnd(), "yyyy.MM"));
                System.out.println("excel表中：" + courseBuildRead);
                BeanUtils.copyProperties(courseBuildRead, courseBuild, new String[]{"startAndEnd", "headAndPlayers", "level1", "category1", "category2", "category3"});
                System.out.println("转换为：" + courseBuild);
                courseBuildList.add(courseBuild);

            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                if (r.getCode() == ResultCode.SUCCESS) {
                    //向数据库插入数据
                    saveData();
                } else {
                    r.data("errorMsg", errorList);
                }
            }

            /**
             * 数据类型转换异常处理
             * @param exception
             * @param context
             * @throws Exception
             */
            @Override
            public void onException(Exception exception, AnalysisContext context) throws Exception {
                if (exception instanceof ExcelDataConvertException) {
                    ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;

                    //向errorList中添加信息
                    r.code(ResultCode.ERROR);
                    System.out.println("行：" + excelDataConvertException.getRowIndex() + "列" + excelDataConvertException.getColumnIndex());
                    errorList.add("行：" + excelDataConvertException.getRowIndex() + "列" + excelDataConvertException.getColumnIndex());
//                    LOGGER.error("第{}行，第{}列解析异常", excelDataConvertException.getRowIndex(),
//                            excelDataConvertException.getColumnIndex());
                }
            }

            //存数据库操作
            private void saveData() {
                for (CourseBuild courseBuild : courseBuildList) {
                    courseBuildMapper.insert(courseBuild);
                    System.out.println("插入成功");
                }

                //r中写入成功信息
                r.code(ResultCode.SUCCESS).message("插入成功");
            }

        }).headRowNumber(5).sheet().doRead();
        return r;
    }

    /**
     * excel写出
     *
     * @return
     */
    @Transactional
    @Override
    public R writeExcel(HttpServletResponse response, CourseBuild courseBuild) {
        List<CourseBuild> courseBuilds = new ArrayList<>();
        if (courseBuild == null) {
            //从数据库中查询对应表格
            courseBuilds = courseBuildMapper.selectList(null);

        } else {
            QueryWrapper<CourseBuild> courseBuildQueryWrapper = new QueryWrapper<>();
            if (courseBuild.getCategory() != null) {
                courseBuildQueryWrapper.eq("category", courseBuild.getCategory());
            }
            if (courseBuild.getLevel() != null) {
                courseBuildQueryWrapper.eq("level", courseBuild.getLevel());
            }
            if (courseBuild.getName() != null) {
                courseBuildQueryWrapper.like("name", courseBuild.getName());
            }
            if (courseBuild.getHead() != null) {
                courseBuildQueryWrapper.like("head", courseBuild.getHead());
            }
            if (courseBuild.getPlayers() != null) {
                courseBuildQueryWrapper.like("players", courseBuild.getPlayers());
            }
            //从数据库中查询对应表格
            courseBuilds = courseBuildMapper.selectList(courseBuildQueryWrapper);
        }

        //创建list存放导出bean
        List<CourseBuildRead> courseBuildReads = new ArrayList<>();

        //将数据库对应的bean复制给导出表格的bean
        for (int i = 0; i < courseBuilds.size(); i++) {
            CourseBuildRead courseBuildRead = new CourseBuildRead();
            BeanUtils.copyProperties(courseBuilds.get(i), courseBuildRead, new String[]{"category", "level", "start", "end"});
            courseBuildRead.setStart(courseBuilds.get(i).getStart().substring(0, 7));
            courseBuildRead.setEnd(courseBuilds.get(i).getEnd().substring(0, 7));
            courseBuildRead.setHeadAndPlayers(courseBuildRead.getHead() + "，" + courseBuildRead.getPlayers());
            courseBuildRead.setStartAndEnd(courseBuildRead.getStart() + "-" + courseBuildRead.getEnd());


            if ("在线开放课程".equals(courseBuilds.get(i).getCategory())) {
                courseBuildRead.setCategory("√");
            } else if ("线上线下混合式一流".equals(courseBuilds.get(i).getCategory())) {
                courseBuildRead.setCategory1("√");
            } else if ("线下一流".equals(courseBuilds.get(i).getCategory())) {
                courseBuildRead.setCategory2("√");
            } else if ("社会实践一流".equals(courseBuilds.get(i).getCategory())) {
                courseBuildRead.setCategory3("√");
            }

            if ("省级".equals(courseBuilds.get(i).getLevel())) {
                courseBuildRead.setLevel("√");
            } else if ("校级".equals(courseBuilds.get(i).getLevel())) {
                courseBuildRead.setLevel1("√");
            }

            courseBuildRead.setNum(i + 1);
            courseBuildReads.add(courseBuildRead);

        }
        //导出(匿名内部类SheetWriteHandler
        try {
            String fileName = URLEncoder.encode("sheet09课程建设", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream()).withTemplate(filePathConfig.writeExcelFilePath + "sheet09Template.xlsx").registerWriteHandler(new SheetWriteHandler() {
                @Override
                public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

                }

                @Override
                public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

                }
            }).sheet().doFill(courseBuildReads);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.OK();
    }

    /**
     * 查询所有信息
     *
     * @return
     */
    @Override
    public R selectAllCourseBuild(String current, String limit) {
        Page<CourseBuild> courseBuildPage = new Page<>(Integer.valueOf(current), Integer.valueOf(limit));
        QueryWrapper<CourseBuild> courseBuildQueryWrapper = new QueryWrapper<>();
        courseBuildQueryWrapper.select(CourseBuild.class, info -> !info.getColumn().equals("gmt_create")
                && !info.getColumn().equals("gmt_modified"));
        IPage<CourseBuild> courseBuildIPage = courseBuildMapper.selectPage(courseBuildPage, courseBuildQueryWrapper);
        List<CourseBuild> records = courseBuildIPage.getRecords();
        return R.OK().data("list", records).data("pages", courseBuildIPage.getPages()).data("total", courseBuildIPage.getTotal());
    }

    /**
     * 条件查询
     *
     * @param
     * @return
     */
    @Override
    public R courseBuildConditionalQuery(CourseBuildRead courseBuildRead, String current, String limit) {
        Page<CourseBuildRead> courseBuildReadPage = new Page<>(Integer.valueOf(current), Integer.valueOf(limit));
        IPage<CourseBuildRead> courseBuildReadIPage = courseBuildMapper.courseBuildConditionalQuery(courseBuildReadPage, courseBuildRead);
        List<CourseBuildRead> records = courseBuildReadIPage.getRecords();
        List<CourseBuild> courseBuildList = new ArrayList<>();
        for (int i = 0; i < records.size(); i++) {
            CourseBuild courseBuild = new CourseBuild();
            BeanUtils.copyProperties(records.get(i), courseBuild);
            courseBuildList.add(courseBuild);
        }
        return courseBuildList.size() != 0 ? R.OK().data("list", courseBuildList).data("pages", courseBuildReadIPage.getPages()).data("total", courseBuildReadIPage.getTotal()) : R.OK().message("您所查询的信息不存在").data("list", courseBuildList);
    }

    /**
     * 更新
     *
     * @param courseBuild
     * @return
     */
    @Override
    public R updateCourseBuild(CourseBuild courseBuild) {
        int update = courseBuildMapper.updateById(courseBuild);
        return update == 1 ? R.OK().message(courseBuild.getId() + courseBuild.getName() + "修改成功") : R.ERROR().code(ResultCode.UPDATEERROR).message(courseBuild.getId() + courseBuild.getName() + "修改失败");
    }

    /**
     * 删除
     *
     * @param courseBuild
     * @return
     */
    @Transactional
    @Override
    public R deleteCourseBuildById(CourseBuild courseBuild) {
        int id1 = courseBuildMapper.deleteById(courseBuild.getId());
        return id1 == 1 ? R.OK().message("删除成功") : R.ERROR().code(ResultCode.DELETEERROR).message("删除失败");
    }

    /**
     * 新增
     *
     * @param courseBuild
     * @return
     */
    @Override
    public R insertCourseBuild(CourseBuild courseBuild) {
        courseBuild.setStart(DateValidationUtil.dateValidation(courseBuild.getStart(), "yyyy.MM"));
        courseBuild.setEnd(DateValidationUtil.dateValidation(courseBuild.getEnd(), "yyyy.MM"));
        int insert = courseBuildMapper.insert(courseBuild);
        return insert == 1 ? R.OK().message(courseBuild.getId() + courseBuild.getName() + "添加成功") : R.ERROR().message(courseBuild.getId() + courseBuild.getName() + "添加失败");
    }

}
